home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
others
/
ole_101.zip
/
PATRON.ZIP
/
FILE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-13
|
13KB
|
493 lines
/*
* FILE.C
*
* Functions for handling dirty files and processing File menu commands.
*
* Functions:
* WindowTitleSet
* FDirtySet, FCleanVerify
* FFileNew, FFileOpen, FFileSave, FFileSaveAs, FFileExit, FFileClose
*
* This file contains the only functions that manipulate the fDirty flag.
*
* Copyright(c) Microsoft Corp. 1992 All Rights Reserved
*
*/
#include <windows.h>
#include <ole.h>
#include "oclient.h"
#include "blackbox.h"
#include "patron.h"
/*
* WindowTitleSet
*
* Purpose:
* Handles changing the window's caption bar depending on the file
* that is loaded.
*
* Parameters:
* pGlob LPGLOBALS to the global variable block.
*
* Return Value:
* none.
*/
void FAR PASCAL WindowTitleSet(LPGLOBALS pGlob)
{
char szTitle[CCHPATHMAX];
LPSTR pszT;
pszT=pGlob->szFile;
if (0!=lstrcmp(pszT, rgpsz[IDS_UNTITLED]))
pszT=PszFileFromPath(pGlob->szFile);
wsprintf(szTitle, "%s - %s", (LPSTR)rgpsz[IDS_CAPTION], pszT);
SetWindowText(pGlob->hWnd, szTitle);
return;
}
/*
* FDirtySet
*
* Purpose:
* Sets or clears the global 'dirty' flag returning the previous state
* of that same flag.
*
* Parameters:
* fDirty BOOL used to set the value of the pGLob->fDirty flag.
*
* Return Value:
* BOOL Previous value of the dirty flag.
*/
BOOL FAR PASCAL FDirtySet(BOOL fDirty)
{
BOOL fPrevious;
fPrevious=pGlob->fDirty;
pGlob->fDirty=fDirty;
return fPrevious;
}
/*
* FCleanVerify
*
* Purpose:
* Checks the pGLob->fDirty flag, and if set, displays a message
* box informing the user that the file is dirty and asking if
* the file should be saved. If the user chooses to save the
* file, they are prompted with the File Save As dialog.
*
* Parameters:
* pGlob LPGLOBALS to global varaible block.
*
* Return Value:
* BOOL TRUE if
* 1. The user saved the file
* 2. The user said NO
* 3. pGlob->fDirty is FALSE.
*
* FALSE if
* 1. User pressed Cancel
* 2. User pressed Yes but cancelled the Save As dialog.
*/
BOOL FAR PASCAL FCleanVerify(LPGLOBALS pGlob, LPDOCUMENT pDoc)
{
BOOL fRet;
DWORD dwRet;
OLESTATUS os;
if (pGlob->fDirty)
{
dwRet=(DWORD)MessageBox(pGlob->hWnd, rgpsz[IDS_FILEDIRTY],
rgpsz[IDS_CAPTION], MB_YESNOCANCEL);
switch (LOWORD(dwRet))
{
case IDCANCEL:
fRet=FALSE;
break;
case IDNO:
/*
* Inform OLECLI that this document was not changed on disk
* since the last save.
*/
os=OleRevertClientDoc(pDoc->lh);
fRet=(OLE_OK==os);
break;
case IDYES:
fRet=FFileSave(pGlob, pDoc, FALSE);
break;
}
}
return fRet;
}
/*
* FFileNew
*
* Purpose:
* Confirms the new file with the user and cleans out the Polyline
* image.
*
* Parameters:
* pGlob LPGLOBALS to the global variable block.
* pDoc LPDOCUMENT of the document holding objects.
*
* Return Value:
* BOOL TRUE if the function succeeded, FALSE otherwise.
*
*/
BOOL FAR PASCAL FFileNew(LPGLOBALS pGlob, LPDOCUMENT pDoc)
{
if (!FCleanVerify(pGlob, pDoc))
return FALSE;
//Release all the object windows.
FFileClose(pGlob, pDoc);
lstrcpy(pGlob->szFile, rgpsz[IDS_UNTITLED]);
WindowTitleSet(pGlob);
//Act like we're starting the applciation again with no initial file.
return FFileOpen(pGlob, pDoc, TRUE);
}
/*
* FFileOpen
*
* Purpose:
* Reads the contents of a file. If fStartup is TRUE, we assume that
* pGlob->szFile contains a startup filename or just NULLs, in which
* case we use '(Untitled).' If fStartup is FALSE, then we prompt the
* user to save changes if ncessary and retrieve a new file to open.
*
* Parameters:
* pGlob LPGLOBALS to the global variable block.
* pDoc LPDOCUMENT of the document holding objects.
* fStartup BOOL indicates if the function is being called
* to load an initial file on startup (TRUE) or if
* it's in response to a user's menu choice (FALSE).
*
* Return Value:
* BOOL TRUE if the function succeeded, FALSE otherwise.
*
*/
BOOL FAR PASCAL FFileOpen(LPGLOBALS pGlob, LPDOCUMENT pDoc, BOOL fStartup)
{
OLESTATUS os;
PATRON ptn;
BOOL fOK=TRUE;
BOOL fUntitled=FALSE;
if (!fStartup)
{
if (!FCleanVerify(pGlob, pDoc))
return FALSE;
fOK=FFileDialog(pGlob->hWnd, pGlob->hInst, rgpsz[IDS_DEFEXT],
rgpsz[IDS_FILEOPENFILTER], pGlob->szFile,
rgpsz[IDS_FILEOPEN], TRUE);
/*
* If the user pressed Cancel in the dialog, then we're still OK.
* Nothing has yet caused an error.
*/
if (!fOK)
return TRUE;
//Clean out the existing document.
FFileClose(pGlob, pDoc);
}
else
{
if (0==pGlob->szFile[0])
{
lstrcpy(pGlob->szFile, rgpsz[IDS_UNTITLED]);
fUntitled=TRUE;
}
}
WindowTitleSet(pGlob);
/*
* OLE: Register a new client document with the given filename. If
* we're starting, then this is the filename we had on the command
* line or it's '(Untitled).'
*/
os=OleRegisterClientDoc(rgpsz[IDS_CLASSPATRON], pGlob->szFile, 0L, &pDoc->lh);
if (OLE_OK!=os)
return FALSE;
//If we have a filename, attempt to load it.
if (!fUntitled)
{
if (FPtnFileRead(pGlob->szFile, &ptn, pGlob->hWnd, pDoc))
{
//If opening succeeds, move the window and update links.
SetWindowPos(pGlob->hWnd, NULL, ptn.rc.left, ptn.rc.top,
ptn.rc.right-ptn.rc.left, ptn.rc.bottom-ptn.rc.top,
SWP_NOZORDER);
pGlob->fOpenFile=TRUE;
/*
* OLE: Ask the user if they want to update automatic AND
* manual links and do so if they respond Yes. FOLELinksUpdate
* only cares if FPtnFileRead counted any non-updated links.
*/
FOLELinksUpdate(pGlob->hWnd, pGlob->hInst, pDoc);
fOK=TRUE;
}
else
{
//If opening fails, then rename the document to '(Untitled).'
lstrcpy(pGlob->szFile, rgpsz[IDS_UNTITLED]);
WindowTitleSet(pGlob);
os=OleRenameClientDoc(pDoc->lh, pGlob->szFile);
fOK=(OLE_OK==os);
}
}
FDocumentFileSet(pDoc, pGlob->szFile);
FDirtySet(FALSE);
return fOK;
}
/*
* FFileSave
*
* Purpose:
* Writes the file to a known filename, requiring that the user has
* previously used FileOpen or FileSaveAs in order to have a filename.
*
* Parameters:
* pGlob LPGLOBALS to the global variable block.
* pDoc LPDOCUMENT of the document holding objects.
* fSaveAs BOOL indicates if this is being called as a result
* of a FileSaveAs, in which case we change the call
* to OleSavedClientDoc to OleRenameClientDoc.
*
* Return Value:
* BOOL TRUE if the function succeeded, FALSE otherwise.
*
*/
BOOL FAR PASCAL FFileSave(LPGLOBALS pGlob, LPDOCUMENT pDoc, BOOL fSaveAs)
{
OLESTATUS os;
PATRON ptn;
/*
* Note: Calling FFileSaveAs will reenter this function as well,
* but always with fSaveAs==TRUE, so we'll never get stuck in a loop.
*/
if (!pGlob->fOpenFile && !fSaveAs)
return FFileSaveAs(pGlob, pDoc);
//Get the data.
ptn.wVerMajor=VERSIONMAJOR;
ptn.wVerMinor=VERSIONMINOR;
GetWindowRect(pGlob->hWnd, &ptn.rc);
//Indicate how many objects we store here. One object per BlackBox.
ptn.cObjects=pDoc->cObjects;
//Go write the mess.
if (!FPtnFileWrite(pGlob->szFile, &ptn, pDoc))
return FALSE;
//Note that FFileSaveAs calls WindowTitleSet for this new name.
if (fSaveAs)
{
os=OleRenameClientDoc(pDoc->lh, pGlob->szFile);
FDocumentFileSet(pDoc, pGlob->szFile);
}
else
os=OleSavedClientDoc(pDoc->lh);
FDirtySet(FALSE);
pGlob->fOpenFile=TRUE;
return TRUE;
}
/*
* FFileSaveAs
*
* Purpose:
* Invokes the common dialog for Save As to get a filename then
* writes the PATRON data to that file, creating if necessary.
*
* Parameters:
* pGlob LPGLOBALS to the global variable block.
* pDoc LPDOCUMENT of the document holding objects.
*
* Return Value:
* BOOL TRUE if the function succeeded, FALSE otherwise.
*
*/
BOOL FAR PASCAL FFileSaveAs(LPGLOBALS pGlob, LPDOCUMENT pDoc)
{
BOOL fOK;
//Go retrieve a new filename.
fOK=FFileDialog(pGlob->hWnd, pGlob->hInst, rgpsz[IDS_DEFEXT],
rgpsz[IDS_FILEOPENFILTER], pGlob->szFile,
rgpsz[IDS_FILESAVEAS], FALSE);
if (fOK)
{
//We now have a filename, so take advantage of FFileSave.
fOK=FFileSave(pGlob, pDoc, TRUE);
pGlob->fOpenFile=fOK;
if (fOK)
WindowTitleSet(pGlob);
}
return fOK;
}
/*
* FFileExit
*
* Purpose:
* Handles the File/Exit menu command, verifying dirty files as necessary.
*
* Parameters:
* pGlob LPGLOBALS to the global variable block.
*
* Return Value:
* BOOL TRUE if the application can exit, FALSE otherwise.
*/
BOOL FAR PASCAL FFileExit(LPGLOBALS pGlob, LPDOCUMENT pDoc)
{
if (!FCleanVerify(pGlob, pDoc))
return FALSE;
FFileClose(pGlob, pDoc);
return TRUE;
}
/*
* FFileClose
*
* Purpose:
* Closes a document, regardless of whether is was saved or not.
* This function is meant to be used from operations like File Open
* after that operation has saved any necessary changes.
*
* Parameters:
* pGlob LPGLOBALS to the global variable block.
* pDoc LPDOCUMENT of the document holding objects.
*
* Return Value:
* BOOL TRUE if the application can exit, FALSE otherwise.
*/
BOOL FAR PASCAL FFileClose(LPGLOBALS pGlob, LPDOCUMENT pDoc)
{
OLESTATUS os;
//Release all objects and wait for each to receive OLE_RELEASE.
pDoc->cWait=0;
FObjectsEnumerate(pDoc, FEnumClose, 0L);
FOLEReleaseWait(TRUE, pDoc, NULL);
//Clear all the windows.
SendMessage(pGlob->hWnd, WM_COMMAND, IDM_EDITCLEARALL, 0L);
/*
* Tell OLECLI that this document is going away. OleRevokeClientDoc
* does not return OLE_WAIT_FOR_RELEASE.
*/
os=OleRevokeClientDoc(pDoc->lh);
pGlob->fOpenFile=FALSE;
FDirtySet(FALSE);
return (OLE_OK==os);
}
/*
* FEnumClose
*
* Purpose:
* Enumeration callback function for use from FFileClose when it
* calls FObjectsEnumerate. For each object we call OleRelease,
* and if it returns OLE_WAIT_FOR_RELEASE we increment pDoc->cWait.
* After this enumeration is complete, FFileClose can call FOLEReleaseWait
* to wait for all objects.
*
* Parameters:
* pDoc LPDOCUMENT identifying the owner of all objects.
* pObj LPOBJECT identifying the current object.
* dw DWORD for extra data, unused.
*
* Return Value:
* BOOL TRUE--we want to enumerate everything.
*/
BOOL FAR PASCAL FEnumClose(LPDOCUMENT pDoc, LPOBJECT pObj, DWORD dw)
{
OLESTATUS os;
os=OleRelease(pObj->pObj);
OsError(os, pDoc, pObj, FALSE);
return TRUE;
}